package top.infopub.mgr.om.web;


import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import top.infopub.mgr.common.page.ParamPage;
import top.infopub.mgr.common.vo.ErrorCodeEnum;
import top.infopub.mgr.common.vo.RspVo;
import top.infopub.mgr.flow.web.GenericFlowController;
import top.infopub.mgr.hr.service.DeptInfoService;
import top.infopub.mgr.hr.service.OrgInfoService;
import top.infopub.mgr.hr.service.StaffInfoService;
import top.infopub.mgr.hr.service.StaffOfficeService;
import top.infopub.mgr.mkt.service.DiscloseProService;
import top.infopub.mgr.om.domain.PaymentApplyDomain;
import top.infopub.mgr.om.service.PaymentApplyService;
import top.infopub.mgr.om.vo.PaymentApplyVo;
import top.infopub.mgr.sg.service.CoopInfoService;
import top.infopub.mgr.util.FileHelper;
import top.infopub.mgr.util.FirstSpellUtil;
import top.infopub.mgr.util.LogUtil;
import top.infopub.mgr.util.LogUtil.AcctionType;
import top.infopub.mgr.util.LogUtil.LogModelType;
import top.infopub.model.hr.OrgInfo;
import top.infopub.model.hr.StaffInfo;
import top.infopub.model.om.PaymentApply;
import top.infopub.model.om.PaymentApplyAtt;
import top.infopub.model.om.PaymentApplyDetail;
import top.infopub.security.util.SessionUserUtils;
import top.infopub.security.vo.AuthorizationVO;
import top.infopub.tdp.sys.service.CodeGeneratorConfigService;
import top.infopub.util.IdFactory;

import com.github.pagehelper.Page;


/**
 * 付款申请管理
 * @author wangtao
 * @version 2020年1月15日
 * @see PaymentApplyController
 * @since
 */
@Controller
@RequestMapping("/paymentApply")
public class PaymentApplyController extends GenericFlowController {

    @Autowired
    private PaymentApplyService paymentApplyService;

    @Autowired
    private OrgInfoService orgInfoService;

    @Autowired
    private DeptInfoService deptInfoService;

    @Autowired
    private StaffInfoService staffInfoService;

    @Autowired
    private StaffOfficeService staffOfficeService;

    @Autowired
    private CoopInfoService coopInfoService;

    @Autowired
    private CodeGeneratorConfigService codeGeneratorConfigService;
    
    @Autowired
    private DiscloseProService discloseProService;

    /**
     * 付款申请列表
     * @return
     */
    @RequestMapping("/list")
    public String list() {
        return "om/lay-paymentApply-list";
    }

    /**
     * 付款申请列表数据
     * @return
     */
    @RequestMapping("/queryDataByCondition")
    @ResponseBody
    public RspVo<PaymentApplyDomain> queryDataByCondition(PaymentApplyVo paymentApplyVo,
                                                          ParamPage paramPage) {
        Page<PaymentApplyDomain> page = new Page<PaymentApplyDomain>();
        page.setPageNum(paramPage.getPage());
        page.setPageSize(paramPage.getLimit());
        //查询时，结束日期增加一天
        if (paymentApplyVo.getEndDate() != null) {
            paymentApplyVo.setEndDate(DateUtils.addDays(paymentApplyVo.getEndDate(), 1));
        }
        page = paymentApplyService.selectByDomainWhere(page, paymentApplyVo);
        return RspVo.getSuccessResponse(page.getTotal(), page.getResult());
    }

    /**
     * 付款申请-我审批的列表数据
     * @return
     */
    @RequestMapping("/queryMyCheckDataByCondition")
    @ResponseBody
    public RspVo<PaymentApplyDomain> queryMyCheckDataByCondition(PaymentApplyVo paymentApplyVo,
                                                                 ParamPage paramPage) {
        Page<PaymentApplyDomain> page = new Page<PaymentApplyDomain>();
        page.setPageNum(paramPage.getPage());
        page.setPageSize(paramPage.getLimit());
        //查询时，结束日期增加一天
        if (paymentApplyVo.getEndDate() != null) {
            paymentApplyVo.setEndDate(DateUtils.addDays(paymentApplyVo.getEndDate(), 1));
        }
        paymentApplyVo.setAddBy(SessionUserUtils.getSessionUserId());
        page = paymentApplyService.selectMyCheckByDomainWhere(page, paymentApplyVo);
        return RspVo.getSuccessResponse(page.getTotal(), page.getResult());
    }

    /**
     * 付款申请-新增
     * @return
     */
    @RequestMapping("/add")
    public String add(HttpServletRequest request) {
        String bindOrgId = String.valueOf(SessionUserUtils.getSessionAttribute("bindOrgId"));
        String bindOrgName = String.valueOf(SessionUserUtils.getSessionAttribute("bindOrgName"));
        String bindDeptId = String.valueOf(SessionUserUtils.getSessionAttribute("bindDeptId"));
        String bindDeptName = String.valueOf(SessionUserUtils.getSessionAttribute("bindDeptName"));
        request.setAttribute("bindOrgId", bindOrgId);
        request.setAttribute("bindOrgName", bindOrgName);
        request.setAttribute("bindDeptId", bindDeptId);
        request.setAttribute("bindDeptName", bindDeptName);
        request.setAttribute("areaFirstSpell", FirstSpellUtil.two(bindOrgName));
        AuthorizationVO authorizationVO = SessionUserUtils.getSessionAttributeForUserDtl();

        StaffInfo staffInfo = staffInfoService.selectByPrimaryKey(authorizationVO.getHrStaffId());
        request.setAttribute("staffName", staffInfo.getStaffName());
        request.setAttribute("disclosePros", discloseProService.selectAllWithOrg());

        return "om/lay-paymentApply-add";
    }

    /**
     * 根据id查询付款申请详情  > 注意：方法命名必须为：toDealOrDetail
     * @param id 付款申请Id
     * @return
     * @see
     */
    @RequestMapping("/toDealOrDetail")
    public ModelAndView queryById(HttpServletRequest request, String id, String processDealWith) {
        Map<String, Object> map = new HashMap<String, Object>();
        PaymentApplyDomain paymentApply = paymentApplyService.selectById(id);
        request.setAttribute("modelDetail", paymentApply);
        map.put("paymentApply", paymentApply);
        // 审批flag
        request.setAttribute("processDealWith", processDealWith);
        // 审批data
        processData(request, paymentApply.getProcessId());
        return new ModelAndView("om/lay-paymentApply-detail", map);
    }

    /**
     * 新增付款申请
     * @return
     */
    @SuppressWarnings({"rawtypes"})
    @RequestMapping("/save")
    public @ResponseBody RspVo save(HttpServletRequest request, PaymentApply paymentApply) {

        String[] orderIdx = request.getParameterValues("orderIdx");//子项序号,数据库中不存储此项，只存储以下的accountName，accountNo，openBankName，itemName，paySingle

        String[] accountName = request.getParameterValues("accountName");//子项-支付对象单位
        String[] accountNo = request.getParameterValues("accountNo");//子项-银行帐号
        String[] openBankName = request.getParameterValues("openBankName");//子项-开户行名称
        String[] itemName = request.getParameterValues("itemName");//子项-款项名称
        String[] paySingle = request.getParameterValues("paySingle");//子项-单项金额

        //附件资料
        String[] fileAtt1 = request.getParameterValues("fileAtt1");
        //若附件资料必须上传，下面的验证代码放开、update by wt 2020-01-17
        //        if(fileAtt1.length <1){
        //            return ErrorCodeEnum.ERROR_COMMON_CHECK.getRspVo("运营费用申请相关附件未上传");
        //        }

        AuthorizationVO vo = SessionUserUtils.getSessionAttributeForUserDtl();

        /**
         * 付款申请主表处理
         */
        String id = IdFactory.getUUIDUpper();
        paymentApply.setId(id);
        paymentApply.setAddBy(vo.getId());
        paymentApply.setAddTime(top.infopub.mgr.util.DateUtils.getCurrentDateTime());

        //单据编号
        String codes = codeGeneratorConfigService.generatorCode("om_payment_apply");
        paymentApply.setCodes(codes);
        paymentApply.setProcessId(IdFactory.getUUIDUpper());//关联的审批流程ID
        paymentApply.setProcessStatus("1");//当前审批状态 1=审批中 9=审批完成 10=审批终止
        paymentApply.setUptBy(vo.getId());
        paymentApply.setUptTime(top.infopub.mgr.util.DateUtils.getCurrentDateTime());

        //因为备注非空原因，这里把备注也设置为付款事由
        paymentApply.setMemo(paymentApply.getPayReason());

        //子项处理
        List<PaymentApplyDetail> paymentApplySubs = new ArrayList<PaymentApplyDetail>();
        for (int i = 0; i < orderIdx.length; i++ ) {
            PaymentApplyDetail detailItem = new PaymentApplyDetail();

            String subId = IdFactory.getUUIDUpper();//自动生成主键
            detailItem.setId(subId);
            detailItem.setApplyId(paymentApply.getId());

            detailItem.setAccountName(accountName[i]);
            detailItem.setAccountNo(accountNo[i]);
            detailItem.setOpenBankName(openBankName[i]);
            detailItem.setItemName(itemName[i]);
            detailItem.setPaySingle(new BigDecimal(paySingle[i]));
            detailItem.setAddBy(vo.getId());
            detailItem.setAddTime(top.infopub.mgr.util.DateUtils.getCurrentDateTime());

            //加入子项明细集合
            paymentApplySubs.add(detailItem);
        }

        /**
         * 上传的文件记录加入集合
         */

        //附件上传
        List<PaymentApplyAtt> fileAtts = new ArrayList<PaymentApplyAtt>();
        if (fileAtt1 != null) {
            for (String file : fileAtt1) {
                PaymentApplyAtt paymentApplyAtt = createFileAtt(vo, paymentApply.getId(), file);
                //加入附件集合
                fileAtts.add(paymentApplyAtt);
            }
        }

        //插入付款申请记录
        paymentApplyService.addPaymentApply(paymentApply, paymentApplySubs, fileAtts);

        LogUtil.bizLog(LogModelType.PROJECT, AcctionType.ADD,
            "付款申请 -新增付款申请：项目名=" + paymentApply.getProName(), null);
        return RspVo.getSuccessResponse();
    }

    /**
     * 创建附件数据，取出附件原始名称，附件扩展名、附件存储路径
     * @param vo
     * @param paymentApplyId
     * @param file
     * @return
     */
    private PaymentApplyAtt createFileAtt(AuthorizationVO vo, String paymentApplyId, String file) {
        //资料信息数组
        String[] fileAttStr = file.split("\\|");
        PaymentApplyAtt fileAtt = new PaymentApplyAtt();
        fileAtt.setId(fileAttStr[2]);//PK
        fileAtt.setApplyId(paymentApplyId);//主表Id
        String fileName = fileAttStr[1].substring(0, fileAttStr[1].lastIndexOf("."));
        String suffix = fileAttStr[1].substring(fileAttStr[1].lastIndexOf("."),
            fileAttStr[1].length()).toLowerCase();//后缀转小写
        fileAtt.setFileName(fileName);//文件名
        fileAtt.setFileSuffix(suffix);//文件后缀
        fileAtt.setFilePath(fileAttStr[3]);//文件保存路径
        fileAtt.setAddBy(vo.getId());//添加人
        fileAtt.setAddTime(top.infopub.mgr.util.DateUtils.getCurrentDateTime());//添加时间
        return fileAtt;
    }

    /**
     * 查询所有付款申请记录
     * @param request
     * @return
     * @throws Exception
     */
    @RequestMapping("/getAllPaymentApply")
    @ResponseBody
    public Map<String, Object> getAllPaymentApply() {
        boolean flag = true;
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            List<PaymentApply> paymentApplys = paymentApplyService.selectByEntityWhere(new PaymentApply());
            map.put("paymentApplys", paymentApplys);
        }
        catch (Exception e) {
            log.error("查询所有付款申请记录异常", e);
            flag = false;
        }
        map.put("flag", flag);
        return map;
    }

    /**
     * 根据id查询付款申请记录
     * @param request
     * @return
     * @throws Exception
     */
    @RequestMapping("/getPaymentApplyById")
    @ResponseBody
    public Map<String, Object> getPaymentApplyById(String id) {
        boolean flag = true;
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            PaymentApply paymentApply = paymentApplyService.selectByPrimaryKey(id);

            AuthorizationVO authorizationVO = SessionUserUtils.getSessionAttributeForUserDtl();
            StaffInfo staffInfo = staffInfoService.selectByPrimaryKey(authorizationVO.getHrStaffId());
            paymentApply.setStaffName(staffInfo.getStaffName());
            map.put("paymentApply", paymentApply);
        }
        catch (Exception e) {
            log.error("查询付款申请记录异常", e);
            flag = false;
        }
        map.put("flag", flag);
        return map;
    }

    /**
     * 获取付
     * @param request
     * @return
     * @throws Exception
     */
    @RequestMapping("/getPaymentCompany")
    @ResponseBody
    public Map<String, Object> getPaymentCompany(String proCode) {
        Map<String, Object> map = new HashMap<String, Object>();
        OrgInfo param = new OrgInfo();
        param.setProjectCode(proCode);
        OrgInfo orgInfo = orgInfoService.queryByProjectCode(proCode);
        map.put("orgInfo", orgInfo);
        return map;
    }

    /**
     * 上传附件
     * @param request
     * @param response
     * @return 
     * @throws IOException 
     * @see
     */
    @SuppressWarnings("rawtypes")
    @RequestMapping("/uploadAtt")
    public @ResponseBody RspVo uploadAtt(HttpServletRequest request)
        throws IOException {
        List<String> returnFileStrList = new ArrayList<>();
        MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest)request;
        Map<String, MultipartFile> map = multipartHttpServletRequest.getFileMap();
        if (map != null) {
            for (String name : map.keySet()) {
                MultipartFile file = map.get(name);
                //资料类型
                String types = request.getParameter("types");
                if (StringUtils.isEmpty(types)) {
                    return ErrorCodeEnum.ERROR_COMMON_PARAM.getRspVo("缺少参数");
                }
                if (file == null) {
                    return ErrorCodeEnum.ERROR_COMMON_PARAM.getRspVo("上传文件不能为空");
                }
                // 上传文件
                String fileId = IdFactory.getUUIDSerialNumber();
                // 服务器资源路径
                String serverPath = "paymentApplyAtt";
                String filePath = FileHelper.upload(file, serverPath);
                returnFileStrList.add(types + "|" + file.getOriginalFilename().trim() + "|"
                                      + fileId + "|" + filePath);
                LogUtil.bizLog(LogModelType.PROJECT, AcctionType.ADD, "上传 运营付款申请 附件-文件名:"
                                                                      + filePath + "，文件路径:"
                                                                      + filePath, null);
            }
        }
        return RspVo.getSuccessResponse(returnFileStrList);
    }
}
